/**
 * 方法装饰器
 * 用于缓存函数的返回值
 * @param _ this
 * @param propertyKey 属性名
 * @param descriptor 描述符
 */
export function cache(
  _: any,
  propertyKey: string,
  descriptor: PropertyDescriptor
) {
  // 获取原始方法
  const originalMethod = descriptor.value
  // 创建一个Map对象，用于存储缓存
  const map: Map<string, any> = new Map()
  // 修改原始方法，添加缓存逻辑
  descriptor.value = function (...args: any[]) {
    // 生成缓存键
    const cacheKey = `${propertyKey}_${JSON.stringify(args)}`
    // 如果缓存中存在该键，则直接返回缓存值
    if (map.has(cacheKey)) {
      return map.get(cacheKey)
    }
    // 否则调用原始方法，并将返回值存入缓存
    const result = originalMethod.apply(this, args)
    map.set(cacheKey, result)
    return result
  }
}

/**
 * 测量函数执行时间方法装饰器
 * @param _ this
 * @param propertyKey 属性名
 * @param descriptor 描述符
 */
export function measureTime(
  _: any, // 传入的参数，可以是任意类型
  propertyKey: string, // 函数的名称
  descriptor: PropertyDescriptor // 函数的描述符
) {
  // 获取原始函数
  const originalMethod = descriptor.value
  // 修改函数的描述符，将原始函数替换为一个新的函数
  descriptor.value = function (...args: any[]) {
    // 记录开始时间
    const start = Date.now()
    // 执行原始函数
    const result = originalMethod.apply(this, args)
    // 记录结束时间
    const end = Date.now()
    // 打印函数执行时间
    console.log(`${propertyKey} 耗时: ${end - start}ms`)
    // 返回原始函数的执行结果
    return result
  }
}
